package com.itlong.cloud.controller.finance;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.operate.OperateBusinessChargeDTO;
import com.itlong.cloud.POJO.PO.PropertyCloudServiceAssignmentDataPO;
import com.itlong.cloud.POJO.PO.PropertyCloudServiceCostOrderDataPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.equip.property.IPropertyEquipServiceClient;
import com.itlong.cloud.paymenthub.IOperateBusinessChargeServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.export.ExportUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      运营-商务收费管理控制器
 * </desc>
 *
 * @createDate 2019/08/06
 */
@RestController
@RequestMapping("/finance/businessCharge")
@RefreshScope
public class OperateBusinessChargeController extends BaseController {

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Autowired
    private IOperateBusinessChargeServiceClient iOperateBusinessChargeServiceClient;

    @Autowired
    private IPropertyEquipServiceClient iPropertyEquipServiceClient;

    /**
     * <desc>
     *      分页获取商务收费信息
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/06
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping("getPage")
    public Object getPage(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);

            if (operateBusinessChargeDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (!NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getRoleType(), 1, 2)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (operateBusinessChargeDTO.getRoleType() == 1 && !NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getType(), 0, 2)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (!NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getBusinessAuditStatus(), 1, 3)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Page<OperateBusinessChargeVO> operateBusinessChargeVOPage = iOperateBusinessChargeServiceClient.getPage(operateBusinessChargeDTO);
            Map<String, Object> appendInfoMap = iOperateBusinessChargeServiceClient.getAppendInfo(operateBusinessChargeDTO);
            return new MessageVO(JSON.toJSONString(appendInfoMap), BaseErrorCodeEnum.SUCCESS.getErrorCode(), operateBusinessChargeVOPage);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理getPage】分页获取商务收费信息失败",e);
        }
    }

    /**
     * <desc>
     *      获取商务收费信息详情
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/06
     */
    @ResponseBody
    @PostMapping("getOne")
    public Object getOne(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getOrderIds())
                    || !NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getOperateType(), 1, 2)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<OperateBusinessChargeVO> operateBusinessChargeVOList = iOperateBusinessChargeServiceClient.getOne(operateBusinessChargeDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), operateBusinessChargeVOList);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理getOne】获取商务收费信息详情失败",e);
        }
    }

    /**
     * <desc>
     *      获取业务日志列表
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/11/26
     */
    @ResponseBody
    @PostMapping("getLogPage")
    public Object getLogPage(){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            OperateBusinessChargeDTO operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getOrderIds())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Page<OperateBusinessOperationLogVO> operateBusinessOperationLogVOPage = iOperateBusinessChargeServiceClient.getLogPage(operateBusinessChargeDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), operateBusinessOperationLogVOPage);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理getLogPage】获取业务日志列表失败",e);
        }
    }

    /**
     * <desc>
     *      获取设备详情列表
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/11/26
     */
    @ResponseBody
    @PostMapping("getDevicePage")
    public Object getDevicePage(){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            OperateBusinessChargeDTO operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null ||StringUtils.isBlank(operateBusinessChargeDTO.getProjectId())){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Page<OperateBusinessDeviceVO> operateBusinessDeviceVOPage = iOperateBusinessChargeServiceClient.getDevicePage(operateBusinessChargeDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), operateBusinessDeviceVOPage);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理getDevicePage】获取设备详情列表失败",e);
        }
    }

    /**
     * <desc>
     *      获取该批次号已录入数据的最大结束时间
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/11/25
     */
    @ResponseBody
    @PostMapping("getMaxEndTime")
    public Object getMaxEndTime(){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            OperateBusinessChargeDTO operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getBatchNumber())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Map<String, Object> data = iOperateBusinessChargeServiceClient.getMaxEndTime(operateBusinessChargeDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理getMaxEndTime】获取该批次号已录入数据的最大结束时间失败",e);
        }
    }

    /**
     * <desc>
     *      添加商务收费信息
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/07
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.FINANCE_BUSINESS_CHARGE_ADD_LOG_DESC)
    @ResponseBody
    @PostMapping("save")
    public Object save(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            String ip = HttpProtocolUtil.getIpAddr(request);
            operateBusinessChargeDTO.setIp(ip);
            if (StringUtils.isBlank(operateBusinessChargeDTO.getProjectId())) {
                return new MessageVO(OperateErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
            try {
                sdf.parse(operateBusinessChargeDTO.getEndTime());
                new BigDecimal(operateBusinessChargeDTO.getPaidAmount());
                JSON.parseArray(operateBusinessChargeDTO.getChargeDetail(), PropertyCloudServiceCostOrderDataPO.class);
                JSON.parseArray(operateBusinessChargeDTO.getAssignmentDetail(), PropertyCloudServiceAssignmentDataPO.class);
                JSON.parseArray(operateBusinessChargeDTO.getDeviceDetail(), DeviceBatchNumberDTO.class);
            } catch (Exception e) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            Integer tabCode = iOperateBusinessChargeServiceClient.save(operateBusinessChargeDTO);
            if (tabCode == -1) {
                return new MessageVO(OperateErrorCodeEnum.FINANCE_BUSINESS_CHARGE_EXIST_ERR.getErrorCode());
            }
            if (tabCode == -2) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode(), "今日批次号已达上限，不可再添加");
            }
            return new MessageVO(operateBusinessChargeDTO.getProjectId(), BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理save】添加商务收费信息失败",e);
        }
    }

    /**
     * <desc>
     *      修改商务收费信息
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/07
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.FINANCE_BUSINESS_CHARGE_UPDATE_LOG_DESC)
    @ResponseBody
    @PostMapping("update")
    public Object update(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getOrderId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            String ip = HttpProtocolUtil.getIpAddr(request);
            operateBusinessChargeDTO.setIp(ip);
            if (StringUtils.isBlank(operateBusinessChargeDTO.getProjectId())) {
                return new MessageVO(OperateErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
            try {
                sdf.parse(operateBusinessChargeDTO.getEndTime());
                new BigDecimal(operateBusinessChargeDTO.getPaidAmount());
                JSON.parseArray(operateBusinessChargeDTO.getChargeDetail(), PropertyCloudServiceCostOrderDataPO.class);
                JSON.parseArray(operateBusinessChargeDTO.getAssignmentDetail(), PropertyCloudServiceAssignmentDataPO.class);
                JSON.parseArray(operateBusinessChargeDTO.getDeviceDetail(), HashMap.class);
            } catch (Exception e) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            iOperateBusinessChargeServiceClient.update(operateBusinessChargeDTO);
            return new MessageVO(operateBusinessChargeDTO.getOrderId(), BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理update】修改商务收费信息失败",e);
        }
    }

    /**
     * <desc>
     *      删除商务收费信息
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/07
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.FINANCE_BUSINESS_CHARGE_DELETE_LOG_DESC)
    @ResponseBody
    @PostMapping("delete")
    public Object delete(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getOrderId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            String ip = HttpProtocolUtil.getIpAddr(request);
            operateBusinessChargeDTO.setIp(ip);
            iOperateBusinessChargeServiceClient.delete(operateBusinessChargeDTO);
            return new MessageVO(operateBusinessChargeDTO.getOrderId(), BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理delete】删除商务收费信息失败",e);
        }
    }

    /**
     * <desc>
     *      审核商务收费信息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/11/26
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.FINANCE_BUSINESS_CHARGE_ACCEPT_LOG_DESC)
    @ResponseBody
    @PostMapping("audit")
    public Object audit(){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            OperateBusinessChargeDTO operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getOrderIds()) ||
                    !NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getNowAuditStatus(), 1, 3) ||
                    !NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getAuditStatus(), 0, 2)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if ((operateBusinessChargeDTO.getNowAuditStatus() == 1 && operateBusinessChargeDTO.getAuditStatus() == 0) ||
                    (operateBusinessChargeDTO.getNowAuditStatus() == 3 && operateBusinessChargeDTO.getAuditStatus() == 1)) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            String ip = HttpProtocolUtil.getIpAddr(request);
            operateBusinessChargeDTO.setIp(ip);
            Integer result = iOperateBusinessChargeServiceClient.audit(operateBusinessChargeDTO);
            if (result == -1) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            if (result == -2) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode(), "非赠送商务收费信息的财务已审核状态不能弃审");
            }
            return new MessageVO(operateBusinessChargeDTO.getOrderIds(), BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理audit】审核商务收费信息失败",e);
        }
    }

    /**
     * <desc>
     *      查询物业信息
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/08/07
     */
    @ResponseBody
    @PostMapping("getPropertyInformation")
    public Object getPropertyInformation(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isBlank(operateBusinessChargeDTO.getProjectId())) {
                return new MessageVO(OperateErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            OperatePropertyInformationGetVO operatePropertyInformationGetVO = iOperateBusinessChargeServiceClient.getPropertyInformation(operateBusinessChargeDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), operatePropertyInformationGetVO);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理getPropertyInformation】查询物业信息失败",e);
        }
    }


    /**
     * <desc>
     *      导出商务收费信息
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2020/11/26
     */
    @PostMapping("export")
    public Object export(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);

            if (operateBusinessChargeDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (!NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getRoleType(), 1, 2)) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            if (operateBusinessChargeDTO.getRoleType() == 1 && !NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getType(), 0, 2)) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            if (!NumberHandlerUtil.isInRange(operateBusinessChargeDTO.getBusinessAuditStatus(), 1, 3)) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            Page<OperateBusinessChargeVO> operateBusinessChargeVOPage = iOperateBusinessChargeServiceClient.getPage(operateBusinessChargeDTO);
            List<OperateBusinessChargeVO> operateBusinessChargeVOList = operateBusinessChargeVOPage.getRows();

            if (operateBusinessChargeVOList == null || operateBusinessChargeVOList.isEmpty()){
                return new MessageVO(OperateErrorCodeEnum.EXPORT_DATA_EMPTY_ERR.getErrorCode());
            }

            //将响应列表中的数字代号转换成对应的字符串
            operateBusinessChargeVOList.forEach(operateBusinessChargeVO -> {
                operateBusinessChargeVO.setProjectName(operateBusinessChargeVO.getProjectId() + " " + operateBusinessChargeVO.getProjectName());
                operateBusinessChargeVO.setFeeStatus(OperateBusinessChargeVO.getFeeStatusString(operateBusinessChargeVO.getFeeStatus()));
                operateBusinessChargeVO.setEndStatus(OperateBusinessChargeVO.getEndStatusString(operateBusinessChargeVO.getEndStatus()));
                if (operateBusinessChargeVO.getEndDay() != null && Integer.parseInt(operateBusinessChargeVO.getEndDay()) < 0){
                    String endDayString = String.format("过期%s天", Math.abs(Integer.parseInt(operateBusinessChargeVO.getEndDay())));
                    operateBusinessChargeVO.setEndDay(endDayString);
                }else if (operateBusinessChargeVO.getEndDay() != null && Integer.parseInt(operateBusinessChargeVO.getEndDay()) >= 0){
                    String endDayString = String.format("%s天",Integer.parseInt(operateBusinessChargeVO.getEndDay()));
                    operateBusinessChargeVO.setEndDay(endDayString);
                }

            });

            //调用导出工具类
            String fileItemNames = "序号,批次号,项目名称,任务书,创建时间,收费结束时间,本期收费金额,下期参考收费金额,设备情况,过期倒计时,过期状态,状态";
            String items ="serialNum,batchNumber,projectName,assignmentNumber,createTime,endTime,paidAmount,nextAmount,deviceInfo,endDay,endStatus,feeStatus";
            String fileUrl = ExportUtil.exportByItemsAndNames(operateBusinessChargeVOList, fileItemNames, items, (short) 420,
                    16, "business", FILE_FTP_HOST, FILE_FTP_USERNAME, FILE_FTP_PASSWORD, FILE_FTP_PORT, FILE_ACCESS_URL);

            //导出文件失败
            if (StringUtils.isBlank(fileUrl)){
                return new MessageVO(OperateErrorCodeEnum.EXPORT_FILE_SAVE_ERR.getErrorCode());
            }

            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), (Object)fileUrl);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理export】导出商务收费信息失败",e);
        }
    }


    /**
     * <desc>
     *      商务延期处理
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2020/11/26
     */
    @ResponseBody
    @PostMapping("delay")
    public Object delay(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getDelayEndTime())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iOperateBusinessChargeServiceClient.delay(operateBusinessChargeDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理delay】延期处理失败",e);
        }
    }

    /**
     * <desc>
     *      商务收款确认
     * </desc>
     *
     * @param operateBusinessChargeDTO 商务收费信息DTO
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2020/11/26
     */
    @ResponseBody
    @PostMapping("confirm")
    public Object confirm(OperateBusinessChargeDTO operateBusinessChargeDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateBusinessChargeDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateBusinessChargeDTO.class,request);
            if (operateBusinessChargeDTO == null || StringUtils.isBlank(operateBusinessChargeDTO.getCloudServiceAssignment())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iOperateBusinessChargeServiceClient.confirm(operateBusinessChargeDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理confirm】商务收款确认",e);
        }
    }

    /**
     * <desc>
     *      上传附件
     * <desc/>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/11/25
     */
    @ResponseBody
    @PostMapping("upload")
    public Object upload(HttpServletRequest request){
        try {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (!isMultipart) {
                // 是否是带文件上传的表单
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_RESOURCE_EMPTY_ERR.getErrorCode(), "附件资源不能为空");
            }
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String,MultipartFile> multipartFileMap = multipartRequest.getFileMap();
            if (multipartFileMap.isEmpty()){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_RESOURCE_EMPTY_ERR.getErrorCode(), "附件资源不能为空");
            }
            String uploadInfoUrl = "";
            for (String fileKey : multipartFileMap.keySet()) {
                List<MultipartFile> fileList = multipartRequest.getFiles(fileKey);
                for (MultipartFile mediaFile : fileList) {
                    String fileName = mediaFile.getOriginalFilename();
                    InputStream fileStream = mediaFile.getInputStream();
                    String uploadFileUrl = this.uploadFile(fileStream, fileName);
                    if ("".equals(uploadInfoUrl)) {
                        uploadInfoUrl = uploadFileUrl;
                    } else {
                        uploadInfoUrl = uploadInfoUrl + "," + uploadFileUrl;
                    }
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), (Object) uploadInfoUrl);
        } catch (Exception e) {
            throw new DataAccessException("【运营-商务收费管理upload】上传附件失败",e);
        }
    }

    /**
     * <desc>
     *      校验该批次号下的设备是否到达最大值
     * </desc>
     *
     * @param batchNumber 批次号
     * @param deviceUnique 设备唯一码
     * @return
     * @Author Zhu.yj
     * @createDate  2020/11/30
     */
    @RequestMapping(value = "/deviceVerification", method = RequestMethod.POST)
    public Object deviceVerification(String batchNumber, String deviceUnique, HttpServletRequest request){
        try{
            batchNumber = request.getAttribute("batchNumber") == null ? null : request.getAttribute("batchNumber").toString();
            deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
            if (StringUtils.isBlank(deviceUnique) || StringUtils.isBlank(batchNumber)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Integer deviceType = StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique);
            String projectId = StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique);
            List<String> str= iPropertyEquipServiceClient.getBatchNumber(projectId,"0");
            if(str != null && !str.isEmpty()){
                Integer deviceCountByProject = iPropertyEquipServiceClient.getDeviceCountByType(deviceType,projectId,"");
                Integer limitCountByProject = iPropertyEquipServiceClient.getDeviceCountByBatchNumber(projectId,deviceType+"","");
                deviceCountByProject = deviceCountByProject==null?0:deviceCountByProject;
                if(limitCountByProject==null || limitCountByProject<=deviceCountByProject){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_COUNT_PROJECT_IS_ZERO.getErrorCode());
                }
            }

            //如果批次号不为空时则需校验批次号相对应的设备数量
            Integer deviceCount = iPropertyEquipServiceClient.getDeviceCountByType(deviceType,projectId,batchNumber);
            Integer limitCount = iPropertyEquipServiceClient.getDeviceCountByBatchNumber(projectId,deviceType+"",batchNumber);
            if(deviceCount == null){
                deviceCount = 0;
            }
            if(limitCount<=deviceCount){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_COUNT_PROJECT_IS_LESS.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch(Exception e){
            throw new DataAccessException("【运营_商务收费管理】校验批次号下的设备授权数量是否到达最大值");
        }
    }

    /**
     * <desc>
     *      获取项目下可用的批次号列表
     * </desc>
     *
     * @param  projectId 项目id
     * @return 批次号列表
     * @Author Zhu.yj
     * @createDate  2021/1/4
     */
    @PostMapping("/getProjectBatchNumber")
    public Object getProjectBatchNumber(String projectId, HttpServletRequest request){
        try{
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if (StringUtils.isBlank(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<String> batchNumberList = iOperateBusinessChargeServiceClient.getProjectBatchNumber(projectId);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), batchNumberList);
        }catch (Exception e){
            throw new DataAccessException("【运营_商务收费管理getProjectBatchNumber】获取项目下可用批次号列表失败", e);
        }
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileName 文件名称
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2019/11/25
     */
    private String uploadFile(InputStream inputStream, String fileName) throws IOException {
        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.') + 1, fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.BUSINESS_CHARGE_UPLOAD_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean) resultMap.get("returnCode");
        if (!returnCode) {
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }

}
